#include "gtest/gtest.h"

#include "list.h"


struct foo_pool
{
	struct list_head task_queue;
    /* some attr here */
    int attr;
};

struct foo_node
{
    int value;
    /* some value here */
};

struct foo_node_entry
{
    struct foo_node node;
    struct list_head list;
};

//
TEST(TestAdd, Handles)
{
    struct foo_pool pool;
    INIT_LIST_HEAD(&pool.task_queue);
    
    struct foo_node_entry nd;
    nd.node.value = 1024;

    list_add(&nd.list, &pool.task_queue);

    struct foo_node_entry *p = list_entry(&nd.list, struct foo_node_entry, list);
	
    EXPECT_EQ(p->node.value, 1024);
}

//
TEST(TestAddMore, Handles)
{
    struct foo_pool pool;
    INIT_LIST_HEAD(&pool.task_queue);
    
    struct foo_node_entry nd[5];
    for (int i = 0; i < 5; ++i)
    {
        nd[i].node.value = i;
    }

    for (int i = 0; i < 5; ++i)
    {
        list_add(&nd[i].list, &pool.task_queue);
    }

    bool flag = true;
    struct foo_node_entry *pos;
    int i = 4;
    list_for_each_entry(pos, &pool.task_queue, list)
    {
        std::cout << pos->node.value << "  ";
        if (pos->node.value != i)
        {
            flag = false;
        }
        --i;
    }
    std::cout << std::endl;
	
    EXPECT_EQ(flag, true);
}

//
TEST(TestAddTailMore, Handles)
{
    struct foo_pool pool;
    INIT_LIST_HEAD(&pool.task_queue);
    
    struct foo_node_entry nd[5];
    for (int i = 0; i < 5; ++i)
    {
        nd[i].node.value = i;
    }

    for (int i = 0; i < 5; ++i)
    {
        list_add_tail(&nd[i].list, &pool.task_queue);
    }

    bool flag = true;
    struct foo_node_entry *pos;
    int i = 0;
    list_for_each_entry(pos, &pool.task_queue, list)
    {
        std::cout << pos->node.value << "  ";
        if (pos->node.value != i)
        {
            flag = false;
        }
        ++i;
    }
    std::cout << std::endl;
	
    EXPECT_EQ(flag, true);
}

int main(int argc, char **argv)
{
	::testing::InitGoogleTest(&argc, argv);
	return RUN_ALL_TESTS();
}